﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;

namespace Elentok.Common.Wpf.Helpers
{
  /// <summary>
  /// UI-related methods
  /// </summary>
  public static class WpfHelper
  {
    /// <summary>
    /// Goes up the visual tree until it reaches an ancestor
    /// of type <typeparamref name="T"/>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="current"></param>
    /// <returns></returns>
    public static T FindAncestor<T>(this DependencyObject current)
      where T : DependencyObject
    {
      do
      {
        if (current is T)
          return (T)current;

        current = VisualTreeHelper.GetParent(current);
      }
      while (current != null);
      return null;
    }

    /// <summary>
    /// Finds the <see cref="ListViewItem"/> at a given position
    /// </summary>
    /// <param name="listView"></param>
    /// <param name="mousePosition">coordinates relevant to the listview</param>
    /// <returns></returns>
    public static ListViewItem GetListViewItemFromPoint(this ListView listView, Point mousePosition)
    {
      var result = VisualTreeHelper.HitTest(listView, mousePosition);
      if (result != null && result.VisualHit != null)
      {
        return result.VisualHit.FindAncestor<ListViewItem>();
      }

      return null;
    }

    /// <summary>
    /// Finds the <see cref="TreeViewItem"/> at a given position
    /// </summary>
    /// <param name="treeView"></param>
    /// <param name="mousePosition">Coordinates relative to the treeview</param>
    /// <returns></returns>
    public static TreeViewItem GetTreeViewItemFromPoint(this TreeView treeView, Point mousePosition)
    {
      var result = VisualTreeHelper.HitTest(treeView, mousePosition);
      if (result != null && result.VisualHit != null)
      {
        return result.VisualHit.FindAncestor<TreeViewItem>();
      }

      return null;
    }

    /// <summary>
    /// Similar to the "ItemContainerGenerator.ContainerFromItem" method but works recursively
    /// (returns null if the container for the given item is not found)
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="parent"></param>
    /// <param name="item"></param>
    /// <returns></returns>
    public static T GetContainerFromItem<T>(this ItemsControl parent, object item)
      where T : DependencyObject
    {
      T container = parent.ItemContainerGenerator.ContainerFromItem(item) as T;

      if (container != null)
        return container;

      #region Search in all child ItemsControl controls

      if (parent.Items.Count > 0)
      {
        foreach (object childItem in parent.Items)
        {
          var childItemsControl = parent.ItemContainerGenerator.ContainerFromItem(childItem) as ItemsControl;

          container = childItemsControl.GetContainerFromItem<T>(item);
          if (container != null)
            return container;
        }
      }

      #endregion

      return null;
    }

  }
}
